namespace SharpTalk.Core
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using Base;
    using Data;
    using Diagnostic;
    using Enums;

    /// <summary>
    /// 
    /// </summary>
    public sealed class UserManager : UserManagerBase
    {
        public UserManager(IUserDataProvider dataProvider)
            : base(dataProvider)
        {
           
        }

        public UserManager(IUserDataProvider dataProvider, ITraceProvider trace)
            : base(dataProvider)
        {
            TraceProvider = trace;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="firstName"></param>
        /// <param name="lastName"></param>
        /// <param name="nickName"></param>
        /// <param name="image"></param>
        /// <param name="uri"></param>
        /// <returns></returns>
        public override User Create(string firstName, string lastName, string nickName, byte[] image, string uri)
        {
            TraceMethodCall(MethodBase.GetCurrentMethod());

            if (string.IsNullOrEmpty(firstName) && 
                string.IsNullOrEmpty(lastName) && 
                string.IsNullOrEmpty(nickName))
                return null;

            var user = new User(Guid.NewGuid())
            {
                FirstName = firstName,
                LastName = lastName,
                NickName = nickName,
                Image = image,
                Uri = uri,
                Status = UserStatusEnum.Offline
            };

            return DataProvider.Save(user) ? user : null;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="guid"></param>
        /// <returns></returns>
        public override User Find(Guid guid)
        {
            TraceMethodCall(MethodBase.GetCurrentMethod());
            return DataProvider.Find(guid);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="firstName"></param>
        /// <param name="lastName"></param>
        /// <param name="nickName"></param>
        /// <returns></returns>
        public override List<User> Find(string firstName, string lastName, string nickName)
        {
            TraceMethodCall(MethodBase.GetCurrentMethod());
            if(string.IsNullOrEmpty(firstName) && string.IsNullOrEmpty(lastName) && string.IsNullOrEmpty(nickName))
                return new List<User>();

            return DataProvider.All().Where( u => 
                (!string.IsNullOrEmpty(firstName) && firstName.Equals(u.FirstName, StringComparison.InvariantCultureIgnoreCase)) &&
                (!string.IsNullOrEmpty(lastName) && lastName.Equals(u.LastName, StringComparison.InvariantCultureIgnoreCase)) &&
                (!string.IsNullOrEmpty(nickName) && nickName.Equals(u.NickName,StringComparison.InvariantCultureIgnoreCase))).ToList();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="guid"></param>
        /// <returns></returns>
        public override bool Delete(Guid guid)
        {
            if (guid == Guid.Empty)
            {
                TraceMethodCall(MethodBase.GetCurrentMethod());
                return false;
            }
            return DataProvider.Delete(guid);

        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Delete(User obj)
        {
            TraceMethodCall(MethodBase.GetCurrentMethod());
            return DataProvider.Delete(obj);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Save(User obj)
        {
            TraceMethodCall(MethodBase.GetCurrentMethod());
            return DataProvider.Save(obj);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override List<User> All()
        {
            TraceMethodCall(MethodBase.GetCurrentMethod());
            return DataProvider.All();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override User Update(User obj)
        {
            TraceMethodCall(MethodBase.GetCurrentMethod());
            return obj == null || obj.Guid == Guid.Empty 
                ? null 
                : DataProvider.Update(obj);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="tracked"></param>
        /// <param name="tracker"></param>
        public override void TrackUserChanges(User tracked, User tracker)
        {
            TraceMethodCall(MethodBase.GetCurrentMethod());
            DataProvider.TrackUserChanges(tracked,tracker);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="tracked"></param>
        /// <param name="trackers"></param>
        public override void TrackUserChanges(User tracked, IEnumerable<User> trackers)
        {
            TraceMethodCall(MethodBase.GetCurrentMethod());
            DataProvider.TrackUserChanges(tracked, trackers);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="tracked"></param>
        /// <param name="tracker"></param>
        public override void TrackUserChanges(IEnumerable<Guid> tracked, User tracker)
        {
            TraceMethodCall(MethodBase.GetCurrentMethod());
            DataProvider.TrackUserChanges(tracked, tracker.Guid);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public override IEnumerable<User> GetUserTrackingList(User user)
        {
            TraceMethodCall(MethodBase.GetCurrentMethod());
            return DataProvider.GetUserTrackingList(user);
        }
    }
}